#include "SocketIO.hh"

SocketIO::SocketIO(int fd) 
    : _fd(fd){
    
}

size_t SocketIO::Read_n(char* buf, size_t length) {
    char* p = buf;
    while(length){
        size_t count = ::read(_fd, p, length);
        if(count == -1 && errno == EINTR){
            continue;
        }else if(count == -1){
            ::error(1, errno, "read error");
        }else if(count == 0){
            break;
        }else{
            p += count;
            length -= count;
        }
    }
    return p - buf;
}

size_t SocketIO::Read_line(char* buf, size_t length) {
    char* p = buf;
    while(length){
        size_t count = ::recv(_fd, p, length, MSG_PEEK);
        if(count == -1 && errno == EINTR){
            continue;
        }else if(count == -1){
            ::error(1, errno, "read error");
        }else if(count == 0){
            break;
        }else{
            for(size_t i = 0; i < count; ++i){
                if(p[i] == '\n'){
                    Read_n(p, i + 1);
                    p[i] = '\0';
                    return p - buf  + i + 1;
                }
            }
            Read_n(p, count);
            p += count;
            length -= count;
        }
    }
    return p - buf;    
}

size_t SocketIO::Write_n(const char* buf, size_t length) {
    const char* p  = buf;
    size_t count = 0;
    while(length - count){
        size_t ret = ::write(_fd, p, length - count);
        if(ret == -1 && errno == EINTR){
            continue;
        }else if(ret == -1){
            ::error(1, errno, "write error");
        }else{
            p += ret;
            count += ret;
        }
    }
    return count;
}

SocketIO::~SocketIO() {

}